<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Shell脚本安全检测工具</title>
  <!-- 引入Tailwind CSS -->
  <script src="https://cdn.tailwindcss.com"></script>
  <!-- 引入Font Awesome -->
  <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <!-- 引入JSZip库用于处理ZIP文件 -->
  <script src="https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"></script>
</script>
  
  <!-- 配置Tailwind自定义主题 -->
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: '#165DFF',
            secondary: '#FF7D00',
            danger: '#F53F3F',
            success: '#00B42A',
            warning: '#FF7D00',
            info: '#86909C',
            light: '#F2F3F5',
            dark: '#1D2129',
          },
          fontFamily: {
            inter: ['Inter', 'system-ui', 'sans-serif'],
          },
        },
      }
    }
  </script>
  
  <!-- 自定义工具类 -->
  <style type="text/tailwindcss">
    @layer utilities {
      .content-auto {
        content-visibility: auto;
      }
      .bg-gradient-primary {
        background: linear-gradient(135deg, #165DFF 0%, #4080FF 100%);
      }
      .text-shadow {
        text-shadow: 0 2px 4px rgba(0,0,0,0.1);
      }
      .card-hover {
        transition: all 0.3s ease;
      }
      .card-hover:hover {
        transform: translateY(-5px);
        box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
      }
    }
  </style>
</head>
<body class="font-inter bg-gray-50 min-h-screen flex flex-col">
  <!-- 导航栏 -->
  <header class="bg-white shadow-sm sticky top-0 z-50">
    <div class="container mx-auto px-4 py-3 flex items-center justify-between">
      <div class="flex items-center space-x-2">
        <i class="fa fa-shield text-primary text-2xl"></i>
        <h1 class="text-xl font-bold text-dark">Android Shell脚本安全检测工具</h1>
      </div>
      <nav>
        <ul class="flex space-x-6">
          <li><a href="#" class="text-gray-600 hover:text-primary transition-colors">首页</a></li>
          <li><a href="#about" class="text-gray-600 hover:text-primary transition-colors">关于</a></li>
          <li><a href="#rules" class="text-gray-600 hover:text-primary transition-colors">检测规则</a></li>
        </ul>
      </nav>
    </div>
    <!-- 网站声明 -->
    <div class="bg-primary/10 text-primary text-center py-2 text-sm">
      <p>本站开源且免费，由于作者没有自己的服务器，暂时将网站托管在github，造成访问不便，敬请谅解</p>
    </div>
  </header>

  <!-- 主要内容区 -->
  <main class="flex-grow container mx-auto px-4 py-8">
    <!-- 英雄区域 -->
    <section class="mb-12 text-center">
      <div class="max-w-3xl mx-auto">
        <h2 class="text-[clamp(2rem,5vw,3rem)] font-bold text-dark mb-4 text-shadow">
          检测您的 Shell 脚本安全问题
        </h2>
        <p class="text-gray-600 text-lg mb-8">
          上传单个.sh文件或包含多个.sh文件的.zip（Magisk模块）文件，我们将检测其中是否包含危险命令
        </p>
      </div>
    </section>

    <!-- 文件上传区域 -->
    <section class="mb-12">
      <div class="max-w-3xl mx-auto bg-white rounded-xl shadow-lg p-8 card-hover">
        <div id="drop-area" class="border-2 border-dashed border-gray-300 rounded-lg p-10 text-center mb-8 transition-all hover:border-primary">
          <i class="fa fa-cloud-upload text-4xl text-gray-400 mb-4"></i>
          <p class="text-gray-600 mb-4">拖放.sh文件或.zip文件到此处，或</p>
          <label class="bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-full inline-flex items-center cursor-pointer transition-colors">
            <i class="fa fa-file-text-o mr-2"></i>
            <span>选择文件</span>
            <input type="file" id="file-input" class="hidden" multiple>
          </label>
          <p class="text-xs text-gray-500 mt-4">支持同时上传和检测多个文件，最大文件大小：50MB</p>
        </div>

        <!-- 文件列表预览 -->
        <div id="file-list" class="hidden">
          <h3 class="text-lg font-semibold text-gray-800 mb-4">已选择的文件</h3>
          <div id="selected-files" class="space-y-3"></div>
        </div>

        <!-- 扫描按钮 -->
        <div class="mt-8 text-center">
          <button id="scan-button" class="bg-gradient-primary text-white font-medium py-3 px-8 rounded-lg shadow-lg hover:shadow-xl transition-all disabled:opacity-50 disabled:cursor-not-allowed" disabled>
            <i class="fa fa-search mr-2"></i>开始扫描
          </button>
        </div>
      </div>
    </section>

    <!-- 扫描结果区域 -->
    <section id="results-section" class="mb-12 hidden">
      <div class="max-w-4xl mx-auto">
        <div class="flex justify-between items-center mb-6">
          <h3 class="text-xl font-bold text-dark">扫描结果</h3>
          <div class="flex space-x-2">
            <button id="download-report" class="bg-primary hover:bg-primary/90 text-white px-4 py-2 rounded-lg text-sm transition-colors">
              <i class="fa fa-download mr-1"></i>下载报告
            </button>
            <button id="scan-another" class="bg-white border border-gray-300 hover:bg-gray-50 text-gray-700 px-4 py-2 rounded-lg text-sm transition-colors">
              <i class="fa fa-refresh mr-1"></i>扫描其他文件
            </button>
          </div>
        </div>

        <!-- 结果摘要 -->
        <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
          <div class="bg-white rounded-lg shadow p-4 flex items-center">
            <div class="w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center mr-4">
              <i class="fa fa-file-text-o text-primary text-xl"></i>
            </div>
            <div>
              <p class="text-sm text-gray-500">扫描文件数</p>
              <p id="total-files" class="text-2xl font-bold text-dark">0</p>
            </div>
          </div>
          <div class="bg-white rounded-lg shadow p-4 flex items-center">
            <div class="w-12 h-12 rounded-full bg-danger/10 flex items-center justify-center mr-4">
              <i class="fa fa-exclamation-triangle text-danger text-xl"></i>
            </div>
            <div>
              <p class="text-sm text-gray-500">检测到的危险命令</p>
              <p id="total-issues" class="text-2xl font-bold text-danger">0</p>
            </div>
          </div>
          <div class="bg-white rounded-lg shadow p-4 flex items-center">
            <div class="w-12 h-12 rounded-full bg-success/10 flex items-center justify-center mr-4">
              <i class="fa fa-check-circle text-success text-xl"></i>
            </div>
            <div>
              <p class="text-sm text-gray-500">安全评分</p>
              <p id="safety-score" class="text-2xl font-bold text-success">100%</p>
            </div>
          </div>
        </div>

        <!-- 结果详情 -->
        <div class="bg-white rounded-xl shadow-lg overflow-hidden">
          <div class="border-b border-gray-200 px-6 py-4">
            <h4 class="font-semibold text-gray-800">文件检测详情</h4>
          </div>
          <div id="results-container" class="p-0">
            <!-- 结果将在这里动态生成 -->
            <div class="text-center py-12 text-gray-500">
              <i class="fa fa-spinner fa-spin text-2xl mb-3"></i>
              <p>正在分析文件...</p>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- 关于部分 -->
    <section id="about" class="mb-12">
      <div class="max-w-3xl mx-auto bg-white rounded-xl shadow-lg p-8">
        <h3 class="text-xl font-bold text-dark mb-4">关于此工具</h3>
        <p class="text-gray-600 mb-4">
          这个工具用于检测Shell脚本中可能存在的危险命令，帮助开发者和系统管理员识别潜在的安全风险。
        </p>
        <p class="text-gray-600 mb-4">
          它可以检测单个.sh文件或ZIP压缩包中的多个.sh文件，并提供详细的检测报告，指出每个危险命令的位置和风险级别。
        </p>
        <p class="text-gray-600 mb-4">
          此工具完全在浏览器中运行，不会上传您的文件到任何服务器，确保您的代码安全和隐私。
        <p class="text-gray-600 mb-4">
          任何脚本都有可能具有风险性，本站仅罗列命令包含的风险，请自行斟酌可信度。
        </p>
        <div class="mt-6 p-4 bg-primary/5 rounded-lg border border-primary/20">
          <h4 class="font-semibold text-primary mb-2">免责声明</h4>
          <p class="text-gray-600 text-sm">
            本工具仅作为安全辅助检测使用，检测结果仅供参考。即使脚本通过检测，也请在执行前仔细阅读脚本内容，确认其安全性。
          </p>
        </div>
      </div>
    </section>

    <!-- 检测规则部分 -->
    <section id="rules" class="mb-12">
      <div class="max-w-3xl mx-auto bg-white rounded-xl shadow-lg p-8">
        <h3 class="text-xl font-bold text-dark mb-4">检测规则</h3>
        <p class="text-gray-600 mb-6">
          此工具检测以下类型的危险命令：
        </p>
        
        <div class="space-y-4">
          <div class="flex items-start">
            <div class="w-8 h-8 rounded-full bg-danger/10 flex items-center justify-center mr-3 flex-shrink-0 mt-1">
              <span class="text-danger font-bold">高</span>
            </div>
            <div>
              <h4 class="font-semibold text-gray-800">高风险命令</h4>
              <p class="text-gray-600 text-sm">
                可能导致系统崩溃、数据丢失或严重安全漏洞的命令，如rm -rf, dd if=/dev/zero, 修改系统配置文件等，⚠️极大可能会使设备永久性损坏
              </p>
            </div>
          </div>
          
          <div class="flex items-start">
            <div class="w-8 h-8 rounded-full bg-warning/10 flex items-center justify-center mr-3 flex-shrink-0 mt-1">
              <span class="text-warning font-bold">中</span>
            </div>
            <div>
              <h4 class="font-semibold text-gray-800">中风险命令</h4>
              <p class="text-gray-600 text-sm">
                可能影响系统配置或安全的命令，如chmod, 网络访问命令(wget, curl), 用户管理命令等，错误的执行可能会损坏系统，这些风险是可恢复的，但不承诺会保证数据安全
              </p>
            </div>
          </div>
          
          <div class="flex items-start">
            <div class="w-8 h-8 rounded-full bg-info/10 flex items-center justify-center mr-3 flex-shrink-0 mt-1">
              <span class="text-info font-bold">低</span>
            </div>
            <div>
              <h4 class="font-semibold text-gray-800">低风险命令</h4>
              <p class="text-gray-600 text-sm">
                可能影响系统性能或资源使用的命令，如系统重启命令, 长时间休眠命令, 文件系统操作等，极小可能破坏系统结构，但有可能出现数据丢失或泄露
              </p>
            </div>
          </div>
        </div>
      </div>
    </section>
  </main>

  <!-- 页脚 -->
  <footer class="bg-dark text-white py-8">
    <div class="container mx-auto px-4">
      <div class="flex flex-col md:flex-row justify-between items-center">
        <div class="mb-4 md:mb-0">
          <div class="flex items-center space-x-2">
            <i class="fa fa-shield text-primary text-xl"></i>
            <span class="font-bold text-lg">Android Shell脚本安全检测工具</span>
          </div>
          <p class="text-gray-400 text-sm mt-2">保护您的设备安全</p>
        </div>
        <div class="flex space-x-6">
          <a href="https://github.com/Tobapuww/Tobapuww.github.io" target="_blank" class="text-gray-400 hover:text-white transition-colors">
            <i class="fa fa-github text-xl"></i>
          </a>
          <a href="#" class="text-gray-400 hover:text-white transition-colors">
            <i class="fa fa-twitter text-xl"></i>
          </a>
          <a href="#" class="text-gray-400 hover:text-white transition-colors">
            <i class="fa fa-linkedin text-xl"></i>
          </a>
        </div>
      </div>
      <div class="border-t border-gray-700 mt-6 pt-6 text-center text-gray-400 text-sm">
        <p class="mt-1">&copy; 2025 @Tobapuw 保留所有权利.</p>
      </div>
    </div>
  </footer>

  <!-- 模态框 -->
  <div id="modal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
    <div class="bg-white rounded-lg shadow-xl max-w-3xl w-full max-h-[80vh] overflow-y-auto">
      <div class="border-b border-gray-200 px-6 py-4 flex justify-between items-center">
        <h3 class="font-semibold text-gray-800" id="modal-title">文件详情</h3>
        <button id="close-modal" class="text-gray-500 hover:text-gray-700">
          <i class="fa fa-times"></i>
        </button>
      </div>
      <div class="p-6" id="modal-content">
        <!-- 模态框内容将在这里动态生成 -->
      </div>
      <div class="border-t border-gray-200 px-6 py-4 flex justify-end">
        <button id="close-modal-btn" class="bg-gray-100 hover:bg-gray-200 text-gray-700 px-4 py-2 rounded-lg transition-colors">
          关闭
        </button>
      </div>
    </div>
  </div>

  <!-- 引入安全检测脚本 -->
  <script src="safety-check-improvement.js"></script>
  <script>
    // 全局变量
    let selectedFiles = [];
    let scanResults = [];

    // DOM元素
    const dropArea = document.getElementById('drop-area');
    const fileInput = document.getElementById('file-input');
    const fileList = document.getElementById('file-list');
    const selectedFilesContainer = document.getElementById('selected-files');
    const scanButton = document.getElementById('scan-button');
    const resultsSection = document.getElementById('results-section');
    const resultsContainer = document.getElementById('results-container');
    const totalFilesElement = document.getElementById('total-files');
    const totalIssuesElement = document.getElementById('total-issues');
    const safetyScoreElement = document.getElementById('safety-score');
    const downloadReportButton = document.getElementById('download-report');
    const scanAnotherButton = document.getElementById('scan-another');
    const modal = document.getElementById('modal');
    const modalTitle = document.getElementById('modal-title');
    const modalContent = document.getElementById('modal-content');
    const closeModalButton = document.getElementById('close-modal');
    const closeModalBtn = document.getElementById('close-modal-btn');

    // 初始化事件监听器
    function initEventListeners() {
      // 拖放事件
      ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
        dropArea.addEventListener(eventName, preventDefaults, false);
      });

      function preventDefaults(e) {
        e.preventDefault();
        e.stopPropagation();
      }

      ['dragenter', 'dragover'].forEach(eventName => {
        dropArea.addEventListener(eventName, highlight, false);
      });

      ['dragleave', 'drop'].forEach(eventName => {
        dropArea.addEventListener(eventName, unhighlight, false);
      });

      function highlight() {
        dropArea.classList.add('border-primary');
        dropArea.classList.add('bg-primary/5');
      }

      function unhighlight() {
        dropArea.classList.remove('border-primary');
        dropArea.classList.remove('bg-primary/5');
      }

      dropArea.addEventListener('drop', handleDrop, false);
      
      function handleDrop(e) {
        const dt = e.dataTransfer;
        const files = dt.files;
        handleFiles(files);
      }

      // 文件选择事件
      fileInput.addEventListener('change', function() {
        handleFiles(this.files);
      });

      // 扫描按钮点击事件
      scanButton.addEventListener('click', scanFiles);

      // 下载报告按钮点击事件
      downloadReportButton.addEventListener('click', downloadReport);

      // 扫描另一个文件按钮点击事件
      scanAnotherButton.addEventListener('click', resetScan);

      // 模态框关闭按钮点击事件
      closeModalButton.addEventListener('click', closeModal);
      closeModalBtn.addEventListener('click', closeModal);

      // 点击模态框外部关闭模态框
      modal.addEventListener('click', function(e) {
        if (e.target === modal) {
          closeModal();
        }
      });
    }

    // 处理选择的文件
    function handleFiles(files) {
      if (files.length === 0) return;

      // 过滤出.sh和.zip文件
      const validFiles = Array.from(files).filter(file => {
        const ext = file.name.split('.').pop().toLowerCase();
        return ext === 'sh' || ext === 'zip';
      });

      if (validFiles.length === 0) {
        showNotification('请选择.sh文件或.zip文件', 'error');
        return;
      }

      // 添加到文件列表
      validFiles.forEach(file => {
        // 检查是否已添加相同文件
        const exists = selectedFiles.some(f => f.name === file.name && f.size === file.size && f.lastModified === file.lastModified);
        if (!exists) {
          selectedFiles.push(file);
        }
      });

      updateFileList();
    }

    // 更新文件列表显示
    function updateFileList() {
      if (selectedFiles.length > 0) {
        fileList.classList.remove('hidden');
        scanButton.disabled = false;
      } else {
        fileList.classList.add('hidden');
        scanButton.disabled = true;
      }

      selectedFilesContainer.innerHTML = '';

      selectedFiles.forEach((file, index) => {
        const fileSize = formatFileSize(file.size);
        const fileItem = document.createElement('div');
        fileItem.className = 'bg-gray-50 p-3 rounded-lg flex items-center justify-between';
        fileItem.innerHTML = `
          <div class="flex items-center">
            <i class="fa fa-file-text-o text-primary mr-3"></i>
            <div>
              <p class="font-medium text-gray-800">${file.name}</p>
              <p class="text-xs text-gray-500">${fileSize} - ${new Date(file.lastModified).toLocaleDateString()}</p>
            </div>
          </div>
          <button class="remove-file text-gray-400 hover:text-danger" data-index="${index}">
            <i class="fa fa-times-circle"></i>
          </button>
        `;
        selectedFilesContainer.appendChild(fileItem);
      });

      // 添加删除文件事件监听器
      document.querySelectorAll('.remove-file').forEach(button => {
        button.addEventListener('click', function() {
          const index = parseInt(this.getAttribute('data-index'));
          selectedFiles.splice(index, 1);
          updateFileList();
        });
      });
    }

    // 格式化文件大小
    function formatFileSize(bytes) {
      if (bytes === 0) return '0 Bytes';
      const k = 1024;
      const sizes = ['Bytes', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    // 扫描文件
    async function scanFiles() {
      showLoading(true);
      scanResults = [];
      let totalIssues = 0;
      
      for (const file of selectedFiles) {
        try {
          if (file.name.endsWith('.sh')) {
            // 处理.sh文件
            const content = await readFileAsText(file);
            const result = analyzeShellScript(file.name, content);
            scanResults.push(result);
            totalIssues += result.issues.length;
          } else if (file.name.endsWith('.zip')) {
            // 处理.zip文件
            const zipResults = await analyzeZipFile(file);
            scanResults.push(...zipResults);
            totalIssues += zipResults.reduce((sum, res) => sum + res.issues.length, 0);
          }
        } catch (error) {
          console.error('扫描文件时出错:', error);
          scanResults.push({
            fileName: file.name,
            error: '无法分析文件: ' + error.message,
            issues: []
          });
        }
      }

      showLoading(false);
      displayResults(totalIssues);
    }

    // 读取文件为文本
    function readFileAsText(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.onerror = () => reject(reader.error);
        reader.readAsText(file);
      });
    }

    // 分析ZIP文件
    async function analyzeZipFile(file) {
      return new Promise((resolve, reject) => {
        const zip = new JSZip();
        const results = [];
        
        zip.loadAsync(file)
          .then(zip => {
            // 获取所有.sh文件
            const shFiles = Object.keys(zip.files).filter(filename => filename.endsWith('.sh'));
            
            if (shFiles.length === 0) {
              results.push({
                fileName: file.name,
                error: 'ZIP文件中未找到.sh文件',
                issues: []
              });
              resolve(results);
              return;
            }
            
            // 逐个分析.sh文件
            const analysisPromises = shFiles.map(filename => {
              return zip.files[filename].async('string')
                .then(content => {
                  const result = analyzeShellScript(filename, content);
                  results.push(result);
                })
                .catch(error => {
                  results.push({
                    fileName: filename,
                    error: '无法分析文件: ' + error.message,
                    issues: []
                  });
                });
            });
            
            Promise.all(analysisPromises)
              .then(() => resolve(results))
              .catch(error => reject(error));
          })
          .catch(error => reject(error));
      });
    }

    // 显示加载状态
    function showLoading(isLoading) {
      if (isLoading) {
        resultsSection.classList.remove('hidden');
        resultsContainer.innerHTML = `
          <div class="text-center py-12 text-gray-500">
            <i class="fa fa-spinner fa-spin text-2xl mb-3"></i>
            <p>正在分析文件...</p>
          </div>
        `;
      }
    }

    // 显示扫描结果
     function displayResults(totalIssues) {
        resultsSection.classList.remove('hidden');
        
        // 滚动到结果区域
        resultsSection.scrollIntoView({ behavior: 'smooth' });
        
        // 更新统计信息
        const totalScannedFiles = scanResults.filter(result => !result.error).length;
        totalFilesElement.textContent = totalScannedFiles;
        totalIssuesElement.textContent = totalIssues;
        
        // 计算安全评分
        let safetyScore = 100;
        let hasHighRisk = false;
        let hasMediumRisk = false;
        scanResults.forEach(result => {
            result.issues.forEach(issue => {
                if (issue.severity === 'high') {
                    hasHighRisk = true;
                } else if (issue.severity === 'medium') {
                    hasMediumRisk = true;
                }
            });
        });
        if (hasHighRisk) {
            safetyScore = 0;
        } else if (hasMediumRisk) {
            safetyScore = 50;
        }
        safetyScoreElement.textContent = safetyScore + '分';
        safetyScoreElement.className = `text-2xl font-bold ${safetyScore >= 80 ? 'text-success' : safetyScore >= 50 ? 'text-warning' : 'text-danger'}`;
        
        // 构建结果列表
        if (scanResults.length === 0) {
            resultsContainer.innerHTML = `
                <div class="p-6 text-center text-gray-500">
                    <p>没有扫描到任何文件</p>
                </div>
            `;
            return;
        }
        
        let resultsHTML = '';
        
        scanResults.forEach(result => {
            if (result.error) {
                // 显示错误信息
                resultsHTML += `
                    <div class="border-b border-gray-200 p-6">
                        <div class="flex items-start">
                            <div class="w-8 h-8 rounded-full bg-danger/10 flex items-center justify-center mr-3 flex-shrink-0 mt-1">
                                <i class="fa fa-exclamation-circle text-danger"></i>
                            </div>
                            <div class="flex-grow">
                                <h4 class="font-semibold text-gray-800">${result.fileName}</h4>
                                <p class="text-danger text-sm mt-1">${result.error}</p>
                            </div>
                        </div>
                    </div>
                `;
            } else if (result.encrypted) {
                // 显示加密脚本信息
                resultsHTML += `
                    <div class="border-b border-gray-200 p-6">
                        <div class="flex items-start">
                            <div class="w-8 h-8 rounded-full bg-warning/10 flex items-center justify-center mr-3 flex-shrink-0 mt-1">
                                <i class="fa fa-lock text-warning"></i>
                            </div>
                            <div class="flex-grow">
                                <h4 class="font-semibold text-gray-800">${result.fileName}</h4>
                                <p class="text-warning text-sm mt-1">此脚本已加密，无法分析其内容。⚠️除非你非常信任脚本来源，否则强烈不建议执行该脚本！</p>
                            </div>
                        </div>
                    </div>
                `;
            } else {
                // 显示正常结果
                const severityClass = result.issues.length > 0 ? 
                    (result.issues.some(issue => issue.severity === 'high') ? 'bg-danger/10 text-danger' : 
                     result.issues.some(issue => issue.severity === 'medium') ? 'bg-warning/10 text-warning' : 'bg-success/10 text-success') : 
                    'bg-success/10 text-success';
                
                const severityText = result.issues.length > 0 ? 
                    (result.issues.some(issue => issue.severity === 'high') ? '高风险' : 
                     result.issues.some(issue => issue.severity === 'medium') ? '中风险' : '低风险') : 
                    '安全';
                
                resultsHTML += `
                    <div class="border-b border-gray-200 p-6 hover:bg-gray-50 transition-colors">
                        <div class="flex items-start justify-between">
                            <div class="flex items-start">
                                <div class="w-8 h-8 rounded-full ${severityClass} flex items-center justify-center mr-3 flex-shrink-0 mt-1">
                                    <i class="fa fa-file-text-o"></i>
                                </div>
                                <div class="flex-grow">
                                    <h4 class="font-semibold text-gray-800">${result.fileName}</h4>
                                    <div class="flex items-center mt-1">
                                        <span class="text-xs ${severityClass} px-2 py-0.5 rounded-full mr-2">
                                            ${severityText}
                                        </span>
                                        <span class="text-xs text-gray-500">
                                            ${result.issues.length} 个潜在问题
                                        </span>
                                    </div>
                                </div>
                            </div>
                            <button class="view-details text-primary hover:text-primary/80 text-sm font-medium" data-index="${scanResults.indexOf(result)}">
                                查看详情 <i class="fa fa-angle-right ml-1"></i>
                            </button>
                        </div>
                    </div>
                `;
            }
        });
        
        resultsContainer.innerHTML = resultsHTML;
        
        // 添加查看详情事件监听器
        document.querySelectorAll('.view-details').forEach(button => {
            button.addEventListener('click', function() {
                const index = parseInt(this.getAttribute('data-index'));
                showFileDetails(scanResults[index]);
            });
        });
    }

    // 下载报告
     function downloadReport() {
        // 创建报告内容
        let reportContent = "Shell脚本安全检测报告\n\n";
        reportContent += `生成时间: ${new Date().toLocaleString()}\n`;
        reportContent += `扫描文件总数: ${scanResults.filter(result => !result.error).length}\n`;
        reportContent += `检测到的危险命令总数: ${totalIssuesElement.textContent}\n`;
        reportContent += `安全评分: ${safetyScoreElement.textContent}\n\n`;
        
        // 添加每个文件的结果
        scanResults.forEach(result => {
            reportContent += `文件: ${result.fileName}\n`;
            
            if (result.error) {
                reportContent += `  错误: ${result.error}\n\n`;
            } else if (result.encrypted) {
                reportContent += `  状态: 加密脚本\n  此脚本已加密，无法分析其内容。⚠️除非你非常信任脚本来源，否则强烈不建议执行该脚本！\n\n`;
            } else {
                if (result.issues.length === 0) {
                    reportContent += `  状态: 安全\n  未检测到任何危险命令\n\n`;
                } else {
                    reportContent += `  状态: 检测到 ${result.issues.length} 个潜在问题\n`;
                    
                    result.issues.forEach(issue => {
                        const severityText = issue.severity === 'high' ? '高风险' : 
                                             issue.severity === 'medium' ? '中风险' : '低风险';
                        
                        // 检查是否有安全注释
                        const safetyComments = [];
                        Object.keys(SAFETY_COMMENTS).forEach(key => {
                            if (new RegExp(key).test(issue.lineContent)) {
                                safetyComments.push(SAFETY_COMMENTS[key]);
                            }
                        });
                        
                        reportContent += `  - ${severityText} (第 ${issue.line} 行): ${issue.command}`;
                        if (safetyComments.length > 0) {
                            reportContent += ` [注释: ${safetyComments.join('; ')}]\n`;
                        } else {
                            reportContent += '\n';
                        }
                        reportContent += `    代码: ${issue.lineContent}\n`;
                        const explanations = [];
                        Object.keys(COMMAND_EXPLANATIONS).forEach(key => {
                            if (issue.command.includes(key)) {
                                explanations.push(COMMAND_EXPLANATIONS[key]);
                            }
                        });
                        if (explanations.length > 0) {
                            reportContent += `    说明: ${explanations.join('; ')}\n`;
                        } else {
                            reportContent += `    说明: ${issue.explanation}\n`;
                        }
                    });
                    reportContent += "\n";
                }
            }
        });
        
        // 创建并下载文件
        const blob = new Blob([reportContent], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `shell_script_security_report_${new Date().toISOString().slice(0,10)}.txt`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    }

    // 重置扫描
    function resetScan() {
      selectedFiles = [];
      scanResults = [];
      updateFileList();
      resultsSection.classList.add('hidden');
      dropArea.scrollIntoView({ behavior: 'smooth' });
    }

    // 显示通知
    function showNotification(message, type = 'info') {
      // 创建通知元素
      const notification = document.createElement('div');
      notification.className = `fixed top-4 right-4 px-6 py-3 rounded-lg shadow-lg z-50 transform transition-all duration-300 ease-in-out translate-x-full ${
        type === 'success' ? 'bg-success text-white' : 
        type === 'error' ? 'bg-danger text-white' : 
        type === 'warning' ? 'bg-warning text-white' : 'bg-primary text-white'
      }`;
      notification.innerHTML = `
        <div class="flex items-center">
          <i class="fa ${
            type === 'success' ? 'fa-check-circle' : 
            type === 'error' ? 'fa-exclamation-circle' : 
            type === 'warning' ? 'fa-exclamation-triangle' : 'fa-info-circle'
          } mr-2"></i>
          <span>${message}</span>
        </div>
      `;
      
      // 添加到页面
      document.body.appendChild(notification);
      
      // 显示通知
      setTimeout(() => {
        notification.classList.remove('translate-x-full');
      }, 10);
      
      // 自动关闭
      setTimeout(() => {
        notification.classList.add('translate-x-full');
        setTimeout(() => {
          document.body.removeChild(notification);
        }, 300);
      }, 5000);
    }

    // 初始化应用
    document.addEventListener('DOMContentLoaded', function() {
      initEventListeners();
      showNotification('欢迎使用Shell脚本安全检测工具！', 'info');
    });
  </script>
</body>
</html>
